{% if is_async %}
    {% if is_finite %}
void {{ plugin_name.upper_camel_case }}::{{ name.lower_snake_case }}_async({% for param in params %}{{ param.type_info.name }} {{ param.name.lower_snake_case }}, {% endfor %}const {{ name.upper_camel_case }}Callback& callback)
{
    _impl->{{ name.lower_snake_case }}_async({% for param in params %}{{ param.name.lower_snake_case }}, {% endfor %}callback);
}
    {% else %}
{{ plugin_name.upper_camel_case }}::{{ name.upper_camel_case }}Handle {{ plugin_name.upper_camel_case }}::subscribe_{{ name.lower_snake_case }}({% for param in params %}{{ param.type_info.name }} {{ param.name.lower_snake_case }}, {% endfor %}const {{ name.upper_camel_case }}Callback& callback)
{
    return _impl->subscribe_{{ name.lower_snake_case }}({% for param in params %}{{ param.name.lower_snake_case }}, {% endfor %}callback);
}

void {{ plugin_name.upper_camel_case }}::unsubscribe_{{ name.lower_snake_case }}({{ name.upper_camel_case }}Handle handle)
{
    _impl->unsubscribe_{{ name.lower_snake_case }}(handle);
}
    {% endif %}
{% endif %}

{% if is_sync %}
{% if return_type.is_repeated %}
std::vector<{% if not return_type.is_primitive %}{{ plugin_name.upper_camel_case }}::{% endif %}{{ return_type.inner_name }}>
{% else %}
{% if not return_type.is_primitive %}{{ plugin_name.upper_camel_case }}::{% endif %}{{ return_type.name }}
{%endif -%} {{ plugin_name.upper_camel_case }}::{{ name.lower_snake_case }}({% for param in params %}{{ param.type_info.name }} {{ param.name.lower_snake_case }}{% if not loop.last %}, {% endif %}{% endfor %}) const
{
    return _impl->{{ name.lower_snake_case }}({% for param in params %}{{ param.name.lower_snake_case }}{% if not loop.last %}, {% endif %}{% endfor %});
}
{% endif %}
